package com.atguigu.tingshu.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.user.VipServiceConfig;
import com.atguigu.tingshu.order.helper.SignHelper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.user.client.VipServiceConfigFeignClient;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;
    @Autowired
    private VipServiceConfigFeignClient vipServiceConfigFeignClient;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 订单结算页
     *
     * @param tradeVo
     * @param userId
     * @return
     */
    @Override
    public OrderInfoVo trade(TradeVo tradeVo, Long userId) {
        //本质:给当前对象的属性赋值
        OrderInfoVo orderInfoVo = new OrderInfoVo();

        //原始金额
        BigDecimal originalAmount = new BigDecimal("0.00");
        //减免总金额
        BigDecimal derateAmount = new BigDecimal("0.00");
        //订单总金额
        BigDecimal orderAmount = new BigDecimal("0.00");
        //订单明细
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        //减免明细
        List<OrderDerateVo> orderDerateVoList = new ArrayList<>();

        //获取用户信息
        Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
        Assert.notNull(userInfoVoResult,"查询用户信息失败");
        UserInfoVo userInfoVo = userInfoVoResult.getData();
        Assert.notNull(userInfoVo,"查询用户信息失败");


        //根据购买类型判断
        if (tradeVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)){
            //购买专辑
            Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlbumInfo(tradeVo.getItemId());
            Assert.notNull(albumInfoResult,"查询专辑信息失败");
            AlbumInfo albumInfo = albumInfoResult.getData();
            Assert.notNull(albumInfo,"查询专辑信息失败");

            //判断用户是否购买过专辑
            Result<Boolean> isPaidAlbumResult = this.userInfoFeignClient.isPaidAlbum(tradeVo.getItemId());
            Assert.notNull(isPaidAlbumResult,"查询用户是否购买过专辑");
            Boolean result = isPaidAlbumResult.getData();
            if (result){
                //用户购买过专辑
                throw new GuiguException(ResultCodeEnum.REPEAT_BUY_ERROR);
            }

            //获取到原价
            originalAmount=albumInfo.getPrice();

            // 判断用户身份;
            if (userInfoVo.getIsVip().intValue() == 1 && userInfoVo.getVipExpireTime().after(new Date())) {
                //是VIP折扣
                if (albumInfo.getVipDiscount().compareTo(new BigDecimal("-1")) > 0) {
                    derateAmount = albumInfo.getPrice().multiply(new BigDecimal("10").subtract(albumInfo.getVipDiscount())).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);//四舍五入
                }
            } else {
                if (albumInfo.getDiscount().compareTo(new BigDecimal("-1")) > 0) {
                    //  普通折扣;
                    derateAmount = albumInfo.getPrice().multiply(new BigDecimal("10").subtract(albumInfo.getDiscount())).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
                }
            }
            //实际金额
            orderAmount=originalAmount.subtract(derateAmount);
            //订单明细
            //创建订单明细对象
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemName(albumInfo.getAlbumTitle());
            orderDetailVo.setItemId(tradeVo.getItemId());
            orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
            orderDetailVo.setItemPrice(orderAmount);
            orderDetailVoList.add(orderDetailVo);
            //减免明细
            if (derateAmount.compareTo(new BigDecimal("0.00"))>0){
                OrderDerateVo orderDerateVo = new OrderDerateVo();
                orderDerateVo.setDerateAmount(derateAmount);
                orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_ALBUM_DISCOUNT);
                orderDerateVo.setRemarks("专辑折扣");
                orderDerateVoList.add(orderDerateVo);
            }

        }else if (tradeVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)){
            //购买声音

        }else {
            //购买VIP
            Long itemId = tradeVo.getItemId();// vip_service_config.id;
            Result<VipServiceConfig> vipServiceConfigResult = vipServiceConfigFeignClient.getVipServiceConfig(itemId);
            Assert.notNull(vipServiceConfigResult, "查询vip服务配置失败");
            VipServiceConfig vipServiceConfig = vipServiceConfigResult.getData();
            Assert.notNull(vipServiceConfig, "查询vip服务配置失败");
            //设置原始价格
            originalAmount = vipServiceConfig.getPrice();
            //减免金额
            derateAmount = originalAmount.subtract(vipServiceConfig.getDiscountPrice());
            //实际金额
            orderAmount = vipServiceConfig.getDiscountPrice();
            //订单明细
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemName(vipServiceConfig.getName());
            orderDetailVo.setItemUrl(vipServiceConfig.getImageUrl());
            orderDetailVo.setItemId(itemId);
            orderDetailVo.setItemPrice(orderAmount);
            orderDetailVoList.add(orderDetailVo);
            //减免明细
            if (derateAmount.compareTo(new BigDecimal("0.00")) > 0) {
                //创建对象并赋值
                OrderDerateVo orderDerateVo = new OrderDerateVo();
                orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_VIP_SERVICE_DISCOUNT);
                orderDerateVo.setDerateAmount(derateAmount);
                orderDerateVo.setRemarks("vip服务折扣");
                orderDerateVoList.add(orderDerateVo);
            }

        }

        //声明一个订单交易号
        String tradeNo = UUID.randomUUID().toString().replace("-", "");
        //存储到缓存中 判断key可以利用锁的思想 setnx+setex---setIfAbsent
        String tradeNoKey=userId+":"+tradeNo;
        redisTemplate.opsForValue().setIfAbsent(tradeNoKey,tradeNo,3, TimeUnit.MINUTES);
        orderInfoVo.setTradeNo(tradeNo);
        orderInfoVo.setPayWay("");
        orderInfoVo.setItemType(tradeVo.getItemType());
        orderInfoVo.setOriginalAmount(originalAmount);
        orderInfoVo.setDerateAmount(derateAmount);
        orderInfoVo.setOrderAmount(orderAmount);
        orderInfoVo.setOrderDetailVoList(orderDetailVoList);
        orderInfoVo.setOrderDerateVoList(orderDerateVoList);
        orderInfoVo.setTimestamp(SignHelper.getTimestamp());
        //签名是防止用户非法篡改数据的,保证接口的安全性
        //这里需要保证订单页的数据都不能被随意修改
        String orderJson = JSONObject.toJSONString(orderInfoVo);
        String sign = SignHelper.getSign(JSONObject.parseObject(orderJson,Map.class));
        orderInfoVo.setSign(sign);


        //返回数据
        return orderInfoVo;
    }
}
